/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "S_Px刚体.h"

#include "../A_核心/Px物体形状创建.h"
#include "../A_核心/S_Px核心.h"

using namespace physx;





//PxMaterial* gMaterial = phy->createMaterial(0.8f, 0.8f, 0.5f);






S_Px平面::S_Px平面(physx::PxPhysics* phy, S_物理几何体& geom, S_物理材质& 材质, uint32 key)
	:S_物理体(key)
{
	m_物理引擎枚举 = E_物理引擎::E_物理引擎_PhysX;
	m_Type = E_物理体类型::E_物理体_静态;

	PxPlane& plane = *((PxPlane*)geom.f_get几何体物理对象());
	m_Plane = PxCreatePlane(*phy, PxPlane(plane.n.x, plane.n.y, plane.n.z, plane.d), DEF_PX材质(材质));

	

	
	

	m_Plane->getShapes(&m_Shape, 1);
	PxFilterData qryFilterData;
	qryFilterData.word3 = static_cast<PxU32>(DRIVABLE_SURFACE);
	m_Shape->setQueryFilterData(qryFilterData);

	PxFilterData simFilterData;
	simFilterData.word0 = COLLISION_FLAG_OBSTACLE;
	simFilterData.word1 = COLLISION_FLAG_OBSTACLE_AGAINST;
	//PxFilterData simFilterData(COLLISION_FLAG_GROUND, COLLISION_FLAG_GROUND_AGAINST, 0, 0);
	m_Shape->setSimulationFilterData(simFilterData);
	m_Shape->setContactOffset(0.1);
	//m_Shape->setRestOffset(0.1);

	//m_Px场景s[0]->addActor(*groundPlane);
	m_Type = E_物理体类型::E_物理体_静态;
}

S_Px平面::~S_Px平面() {

}

















S_Px刚体::S_Px刚体(S_Px物理引擎核心* core, S_物理几何体& geom, S_物理材质& 材质, uint32 key) {
	m_物理引擎枚举 = E_物理引擎::E_物理引擎_PhysX;
	m_Type = E_物理体类型::E_物理体_刚体;

	m_刚体 = core->m_Physics->createRigidDynamic(PxTransform(PxIdentity));
	//m_刚体 = core->m_Physics->createRigidDynamic(PxTransform(0.0, 0.0, 0.0));
	m_刚体->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, false);
	m_刚体->setActorFlag(PxActorFlag::eDISABLE_SIMULATION, false);
	//m_刚体->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);
	//PxMaterial* gMaterial = core->m_Physics->createMaterial(0.8f, 0.8f, 0.5f);
	//PxMeshScale 缩放(PxVec3(scale.x, scale.y, scale.z), PxQuat(rot.x, rot.y, rot.z, rot.w));
	//PxTriangleMesh* Px网格 = f_Px_三角碰撞网格(core->m_Physics, core->m_Cooking, mesh);
	//PxTriangleMeshGeometry geom(Px网格, 缩放);
	//PxConvexMesh* Px网格 = f_Px_创建凸包碰撞网格(core->m_Physics, core->m_Cooking, mesh);
	//PxConvexMeshGeometry geom(Px网格, 缩放);
	//PxRigidActorExt::createExclusiveShape(*m_刚体, PxBoxGeometry(2.f, 0.2f, 0.1f), *gMaterial);
	
	//auto b = DEF_PX材质(材质);
	//auto a = DEF_PX几何碰撞(geom);
	//PxMaterial* gMaterial = core->m_Physics->createMaterial(0.8f, 0.8f, 0.5f);
	//m_Shape = PxRigidActorExt::createExclusiveShape(*m_刚体, DEF_PX几何碰撞(geom), *b);
	switch (geom.m_Type) {
	
		case E_物理碰撞几何类型::E_碰撞几何_凸壳:
			{
				//PxConvexMeshGeometry chassisConvexGeom(DEF_PX凸壳碰撞(geom));
				m_Shape = PxRigidActorExt::createExclusiveShape(*m_刚体, *DEF_PX凸壳碰撞(geom), DEF_PX材质(材质));
			}
			break;

		case E_物理碰撞几何类型::E_碰撞几何_方体:
		{
			PxBoxGeometry& box = *((PxBoxGeometry*)geom.f_get几何体物理对象());
			m_Shape = PxRigidActorExt::createExclusiveShape(*m_刚体, box, DEF_PX材质(材质));
		}
		break;
	default:
		break;
	}
	
	//physx::PxConvexMeshGeometry(*(physx::PxTriangleMeshGeometry*)geom.f_get几何体物理对象());
	//auto mesh = DEF_PX几何碰撞(geom);
	//auto mesh = new PxConvexMeshGeometry(DEF_PX凸壳碰撞(geom), PxMeshScale(PxVec3(1, scale.y, scale.z)) );
	
	//m_Shape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, false);
	//m_Shape->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, false);
	m_Shape->setContactOffset(0.1);
}


S_Px刚体::~S_Px刚体() {
	if(m_刚体) m_刚体->release();
}




/*void S_Px刚体::f_构建(S_Px物理引擎核心* core, const S_三角Mesh mesh, const vec3& loc, const vec4& rot, const vec3& scale) {
	m_刚体 = core->m_Physics->createRigidDynamic(PxTransform(loc.x, loc.y, loc.z));
	m_刚体->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, false);
	m_刚体->setActorFlag(PxActorFlag::eDISABLE_SIMULATION, false);
	//m_刚体->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);


	PxMaterial* gMaterial = core->m_Physics->createMaterial(0.8f, 0.8f, 0.5f);
	PxMeshScale 缩放(PxVec3(scale.x, scale.y, scale.z), PxQuat(rot.x, rot.y, rot.z, rot.w));


	//PxTriangleMesh* Px网格 = f_Px_三角碰撞网格(core->m_Physics, core->m_Cooking, mesh);
	//PxTriangleMeshGeometry geom(Px网格, 缩放);
	PxConvexMesh* Px网格 = f_Px_创建凸包碰撞网格(core->m_Physics, core->m_Cooking, mesh);
	PxConvexMeshGeometry geom(Px网格, 缩放);

	
	//PxRigidActorExt::createExclusiveShape(*m_刚体, PxBoxGeometry(2.f, 0.2f, 0.1f), *gMaterial);
	m_Shape = PxRigidActorExt::createExclusiveShape(*m_刚体, geom, *gMaterial);
	
}*/

void S_Px刚体::f_setLocRot(const vec3 & loc, const vec3& r) {
	PxTransform startTransform(PxVec3(loc.x, loc.y, loc.z), PxQuat(PxIdentity));
	if (m_刚体 && m_Type == E_物理体类型::E_物理体_刚体) {
		m_刚体->setGlobalPose(startTransform);
	}
}

void S_Px刚体::f_setPos(const vec3& l) {
	PxTransform startTransform(PxVec3(l.x, l.y, l.z), PxQuat(PxIdentity));
	//if (m_刚体 && m_Type == E_物理类型::e_Px_刚体) {
	m_刚体->setGlobalPose(startTransform);
	//}
}

void S_Px刚体::f_setRot(const vec3& r) {
	auto t = m_刚体->getGlobalPose();
	t.rotate({ r.x, r.y, r.z });
	//if (m_刚体 && m_Type == E_物理类型::e_Px_刚体) {
	m_刚体->setGlobalPose(t);
	//}
}

void S_Px刚体::f_setVel(const vec3& l) {
	PxRigidDynamic* body = (PxRigidDynamic*)(m_刚体);
	if (body) {
		body->setLinearVelocity({ l.x, l.y, l.z });
		//body->setAngularVelocity({ l.x, l.y, l.z });
	}
}

vec3 S_Px刚体::f_getLocation() {
	const auto& p = m_刚体->getGlobalPose().p;
	return { p.x, p.y, p.z };
}














S_Px控制刚体::S_Px控制刚体(S_Px物理引擎核心* core, S_物理几何体& geom, S_物理材质& 材质, uint32 key) {
	m_物理引擎枚举 = E_物理引擎::E_物理引擎_PhysX;
	m_Type = E_物理体类型::E_物理体_控制;
	//m_刚体 = core->m_Physics->createRigidStatic(PxTransform(0.0, 0.0, 0.0));
	m_刚体 = core->m_Physics->createRigidDynamic(PxTransform(0.0, 0.0, 0.0));
	//m_刚体->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, true);
	//m_刚体->setActorFlag(PxActorFlag::eDISABLE_SIMULATION, false);
	//m_刚体->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);
	//PxMaterial* gMaterial = core->m_Physics->createMaterial(0.8f, 0.8f, 0.5f);
	//PxMeshScale 缩放(PxVec3(scale.x, scale.y, scale.z), PxQuat(rot.x, rot.y, rot.z, rot.w));
	//PxTriangleMesh* Px网格 = f_Px_三角碰撞网格(core->m_Physics, core->m_Cooking, mesh);
	//PxTriangleMeshGeometry geom(Px网格, 缩放);
	//PxConvexMesh* Px网格 = f_Px_创建凸包碰撞网格(core->m_Physics, core->m_Cooking, mesh);
	//PxConvexMeshGeometry geom(Px网格, 缩放);
	//PxRigidActorExt::createExclusiveShape(*m_刚体, PxBoxGeometry(2.f, 0.2f, 0.1f), *gMaterial);
	m_刚体->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);
	//auto b = DEF_PX材质(材质);
	//auto a = DEF_PX几何碰撞(geom);

	switch (geom.m_Type) {

		case E_物理碰撞几何类型::E_碰撞几何_凸壳:
		{
			//PxConvexMeshGeometry chassisConvexGeom(DEF_PX凸壳碰撞(geom));
			m_Shape = PxRigidActorExt::createExclusiveShape(*m_刚体, *DEF_PX凸壳碰撞(geom), DEF_PX材质(材质));
		}
		break;

		case E_物理碰撞几何类型::E_碰撞几何_方体:
		{
			PxBoxGeometry& box = *((PxBoxGeometry*)geom.f_get几何体物理对象());
			m_Shape = PxRigidActorExt::createExclusiveShape(*m_刚体, box, DEF_PX材质(材质));
		}
		break;
		default:
			break;
	}

	//PxMaterial* gMaterial = core->m_Physics->createMaterial(0.8f, 0.8f, 0.5f);
	//m_Shape = PxRigidActorExt::createExclusiveShape(*m_刚体, DEF_PX几何碰撞(geom), *b);
	m_Shape = PxRigidActorExt::createExclusiveShape(*m_刚体, DEF_PX几何碰撞(geom), DEF_PX材质(材质));
	//m_Shape->setFlag(PxRigidBodyFlag::eKINEMATIC, false);
	//m_Shape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, false);
	//m_Shape->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, false);
	//m_Shape->setFlag(PxRigidBodyFlag::eKINEMATIC, false)
	//PxRigidBody::setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);
	//m_刚体->setKinematicTarget();
	PxRigidBodyExt::updateMassAndInertia(*m_刚体, m_密度);

}

S_Px控制刚体::~S_Px控制刚体() {
	m_刚体->release();
}

void S_Px控制刚体::f_setLocRot(const vec3& loc, const vec3& r) {
	vec4 q = f_graph_欧拉角转四元数(r);
	PxTransform startTransform(PxVec3(loc.x, loc.y, loc.z), PxQuat(q.x, q.y, q.z, q.w));
	m_刚体->setKinematicTarget(startTransform);
}

void S_Px控制刚体::f_setPos(const vec3& l) {
}

void S_Px控制刚体::f_setRot(const vec3& r) {
}

void S_Px控制刚体::f_setVel(const vec3& l) {
}

vec3 S_Px控制刚体::f_getLocation() {
	const auto& p = m_刚体->getGlobalPose().p;
	return { p.x, p.y, p.z };
}











S_Px静态碰撞::S_Px静态碰撞(S_Px物理引擎核心* core, S_物理几何体& geom, S_物理材质& 材质, uint32 key) {
	m_物理引擎枚举 = E_物理引擎::E_物理引擎_PhysX;
	m_Type = E_物理体类型::E_物理体_控制;
	m_刚体 = core->m_Physics->createRigidStatic(PxTransform(0.0, 0.0, 0.0));
	//m_刚体->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, true);
	//m_刚体->setActorFlag(PxActorFlag::eDISABLE_SIMULATION, false);
	//m_刚体->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);
	//PxMaterial* gMaterial = core->m_Physics->createMaterial(0.8f, 0.8f, 0.5f);
	//PxMeshScale 缩放(PxVec3(scale.x, scale.y, scale.z), PxQuat(rot.x, rot.y, rot.z, rot.w));
	//PxTriangleMesh* Px网格 = f_Px_三角碰撞网格(core->m_Physics, core->m_Cooking, mesh);
	//PxTriangleMeshGeometry geom(Px网格, 缩放);
	//PxConvexMesh* Px网格 = f_Px_创建凸包碰撞网格(core->m_Physics, core->m_Cooking, mesh);
	//PxConvexMeshGeometry geom(Px网格, 缩放);
	//PxRigidActorExt::createExclusiveShape(*m_刚体, PxBoxGeometry(2.f, 0.2f, 0.1f), *gMaterial);
	//auto b = DEF_PX材质(材质);
	//auto a = DEF_PX几何碰撞(geom);

	switch (geom.m_Type) {
		case E_物理碰撞几何类型::E_碰撞几何_凸壳:
		{
			//PxConvexMeshGeometry chassisConvexGeom(DEF_PX凸壳碰撞(geom));
			m_Shape = PxRigidActorExt::createExclusiveShape(*m_刚体, *DEF_PX凸壳碰撞(geom), DEF_PX材质(材质));
		}
		break;

		case E_物理碰撞几何类型::E_碰撞几何_平面:
		{
			PxPlane& plane = *((PxPlane*)geom.f_get几何体物理对象());
			m_刚体 = PxCreatePlane(*core->m_Physics, PxPlane(plane.n.x, plane.n.y, plane.n.z, plane.d), DEF_PX材质(材质));

			m_刚体->getShapes(&m_Shape, 1);
			PxFilterData qryFilterData;
			qryFilterData.word3 = static_cast<PxU32>(DRIVABLE_SURFACE);
			m_Shape->setQueryFilterData(qryFilterData);
			PxFilterData simFilterData(COLLISION_FLAG_GROUND, COLLISION_FLAG_GROUND_AGAINST, 0, 0);
			m_Shape->setSimulationFilterData(simFilterData);
		}
		break;

		case E_物理碰撞几何类型::E_碰撞几何_方体:
		{
			PxBoxGeometry& box = *((PxBoxGeometry*)geom.f_get几何体物理对象());
			m_Shape = PxRigidActorExt::createExclusiveShape(*m_刚体, box, DEF_PX材质(材质));
		}
		break;
		default:
			break;
	}
	//PxMaterial* gMaterial = core->m_Physics->createMaterial(0.8f, 0.8f, 0.5f);
	//m_Shape = PxRigidActorExt::createExclusiveShape(*m_刚体, DEF_PX几何碰撞(geom), *b);
	//m_Shape = PxRigidActorExt::createExclusiveShape(*m_刚体, DEF_PX几何碰撞(geom), DEF_PX材质(材质));
	//m_Shape->setFlag(PxRigidBodyFlag::eKINEMATIC, false);
	//m_Shape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, false);
	//m_Shape->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, false);
	//m_Shape->setFlag(PxRigidBodyFlag::eKINEMATIC, false)
	//PxRigidBody::setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);
	//m_刚体->setKinematicTarget();
	
}

S_Px静态碰撞::~S_Px静态碰撞() {
	m_刚体->release();
}

void S_Px静态碰撞::f_setLocRot(const vec3& loc, const vec3& r) {
	vec4 q = f_graph_欧拉角转四元数(r);
	PxTransform startTransform(PxVec3(loc.x, loc.y, loc.z), PxQuat(q.x, q.y, q.z, q.w));
	m_刚体->setGlobalPose(startTransform);
}

void S_Px静态碰撞::f_setPos(const vec3& l) {
}

void S_Px静态碰撞::f_setRot(const vec3& r) {
}

void S_Px静态碰撞::f_setVel(const vec3& l) {
}

vec3 S_Px静态碰撞::f_getLocation() {
	const auto& p = m_刚体->getGlobalPose().p;
	return { p.x, p.y, p.z };
}















